function latepoint_custom_enhancements() { if ( ! class_exists( 'OsLocationHelper' ) ) return; global $wpdb; $p = $wpdb->prefix . 'latepoint_'; // ── 1. Catégories + lieux ───────────────────────────────────────────── $grouped = []; foreach ( $wpdb->get_results( "SELECT id, name FROM {$p}location_categories ORDER BY FIELD(id,1,5,4)" ) as $c ) $grouped[(string)$c->id] = [ 'name' => $c->name, 'locations' => [] ]; foreach ( $wpdb->get_results( "SELECT id, name, category_id FROM {$p}locations ORDER BY id" ) as $l ) if ( isset( $grouped[(string)$l->category_id] ) ) $grouped[(string)$l->category_id]['locations'][] = [ 'id' => (string)$l->id, 'name' => $l->name ]; // ── 2. Service → locations ──────────────────────────────────────────── $svc_loc = []; foreach ( $wpdb->get_results( "SELECT DISTINCT service_id, location_id FROM {$p}agents_services WHERE location_id > 0" ) as $r ) $svc_loc[(string)$r->service_id][] = (string)$r->location_id; // ── 3. Services ─────────────────────────────────────────────────────── $services = []; foreach ( $wpdb->get_results( "SELECT id, capacity_min, capacity_max, price_min FROM {$p}services" ) as $s ) $services[(string)$s->id] = [ 'min' => max( 1, (int)$s->capacity_min ), 'max' => max( 1, (int)$s->capacity_max ), 'price' => (float)$s->price_min, ]; // ── 4. Agents ───────────────────────────────────────────────────────── $agents_by_svc = []; $all_agents = []; foreach ( $wpdb->get_results( "SELECT DISTINCT ags.service_id, a.id, a.first_name, a.last_name, a.display_name, ma.meta_value AS avatar_id, mb.meta_value AS bio_id FROM {$p}agents_services ags JOIN {$p}agents a ON a.id = ags.agent_id LEFT JOIN {$p}agent_meta ma ON ma.object_id = a.id AND ma.meta_key = 'avatar_image_id' LEFT JOIN {$p}agent_meta mb ON mb.object_id = a.id AND mb.meta_key = 'bio_image_id'" ) as $r ) { $sid = (string)$r->service_id; $aid = (string)$r->id; $full = trim( $r->first_name . ' ' . $r->last_name ); $disp = ! empty( $r->display_name ) ? $r->display_name : $full; $ava = ( ! empty( $r->avatar_id ) && is_numeric( $r->avatar_id ) ) ? ( wp_get_attachment_image_url( (int)$r->avatar_id, 'thumbnail' ) ?: '' ) : ''; $bio = ( ! empty( $r->bio_id ) && is_numeric( $r->bio_id ) ) ? ( wp_get_attachment_image_url( (int)$r->bio_id, 'medium' ) ?: '' ) : ''; $d = [ 'id' => $aid, 'name' => $full, 'display' => $disp, 'init' => strtoupper( mb_substr( $r->first_name, 0, 1 ) . mb_substr( $r->last_name, 0, 1 ) ), 'avatar' => $ava, 'bio' => $bio ]; $agents_by_svc[$sid][] = $d; $all_agents[$aid] = $d; } $all_agents = array_values( $all_agents ); // ── 5. Extras ───────────────────────────────────────────────────────── $extras_by_svc = []; foreach ( $wpdb->get_results( "SELECT se.id, se.name, se.charge_amount, se.multiplied_by_attendees, sse.service_id FROM {$p}service_extras se JOIN {$p}services_service_extras sse ON sse.service_extra_id = se.id WHERE se.status = 'active'" ) as $e ) { $extras_by_svc[(string)$e->service_id][] = [ 'id' => (string)$e->id, 'name' => $e->name, 'price' => (float)$e->charge_amount, 'multiply' => $e->multiplied_by_attendees === 'on', ]; } // ── 6. Auth ─────────────────────────────────────────────────────────── $is_cust = false; $logged_in = false; $cust_id = ''; if ( is_user_logged_in() ) { $is_cust = in_array( 'latepoint_customer', (array)wp_get_current_user()->roles ); $row = $wpdb->get_row( $wpdb->prepare( "SELECT id FROM {$p}customers WHERE wp_user_id=%d LIMIT 1", get_current_user_id() ) ); if ( $row ) { $logged_in = true; $cust_id = (string)$row->id; } } $siret_url = rest_url( 'siret/v1/verify' ); $siret_nonce = wp_create_nonce( 'wp_rest' ); // ── CSS ─────────────────────────────────────────────────────────────── $css = <<<'CSSBLOCK' /* ── Barre de filtres ── */ .lp-bar { display:flex; align-items:flex-end; gap:16px; margin-bottom:16px; flex-wrap:wrap; } .lp-fg { display:flex; flex-direction:column; gap:4px; } .lp-fg > span { font-size:.72rem; font-weight:700; text-transform:uppercase; letter-spacing:.06em; color:var(--ast-global-color-3,#888); } .lp-sel-w { position:relative; display:inline-block; min-width:200px; z-index:999; } .lp-sel-w.wide { min-width:280px; } .lp-sel { appearance:none; -webkit-appearance:none; width:100%; position:relative; z-index:999; pointer-events:all !important; padding:9px 36px 9px 12px; font-family:inherit; font-size:.92rem; line-height:1.4; color:var(--ast-global-color-2,#333); background-color:#fff; background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E"); background-repeat:no-repeat; background-position:right 10px center; border:1.5px solid var(--ast-border-color,#ddd); border-radius:var(--ast-border-radius,6px); box-shadow:0 1px 3px rgba(0,0,0,.06); cursor:pointer; transition:border-color .2s,box-shadow .2s; box-sizing:border-box; } .lp-sel:hover { border-color:var(--ast-global-color-0,#006ae4); } .lp-sel:focus { outline:none; border-color:var(--ast-global-color-0,#006ae4); box-shadow:0 0 0 3px rgba(0,106,228,.15); } /* Bouton voir les prix */ .lp-vp-btn { padding:9px 18px; font-family:inherit; font-size:.92rem; font-weight:600; align-self:flex-end; background:var(--ast-global-color-0,#006ae4); color:#fff; border:none; border-radius:var(--ast-border-radius,6px); cursor:pointer; transition:background .2s; white-space:nowrap; } .lp-vp-btn:hover { background:var(--ast-global-color-1,#0051c0); } /* ── Bloc accès ── */ .lp-access-block { background:#f8f9fa; border:1.5px solid var(--ast-border-color,#e0e0e0); border-radius:var(--ast-border-radius,8px); padding:20px; margin-bottom:20px; } .lp-access-row { display:flex; align-items:flex-start; gap:24px; flex-wrap:wrap; margin-bottom:16px; } .lp-access-or { align-self:center; font-weight:700; color:var(--ast-global-color-3,#888); font-size:.9rem; padding-top:20px; } .lp-notice { font-size:.88rem; color:#92400e; background:#fffbeb; border:1.5px solid #fcd34d; border-radius:6px; padding:10px 14px; margin-bottom:16px; } .lp-loc-required-wrap { border-top:1px solid var(--ast-border-color,#e0e0e0); padding-top:16px; } .lp-loc-notice { font-size:.82rem; color:#dc2626; font-weight:600; margin-bottom:8px; } /* SIRET */ .lp-siret-w { display:flex; flex-direction:column; gap:4px; min-width:260px; } .lp-siret-row { display:flex; gap:8px; align-items:center; flex-wrap:wrap; } .lp-siret-i { padding:9px 12px; font-family:inherit; font-size:.92rem; width:180px; letter-spacing:.08em; border:1.5px solid var(--ast-border-color,#ddd); border-radius:var(--ast-border-radius,6px); box-shadow:0 1px 3px rgba(0,0,0,.06); transition:border-color .2s,box-shadow .2s; box-sizing:border-box; } .lp-siret-i:focus { outline:none; border-color:var(--ast-global-color-0,#006ae4); box-shadow:0 0 0 3px rgba(0,106,228,.15); } .lp-siret-i.ok { border-color:#16a34a; box-shadow:0 0 0 3px rgba(22,163,74,.15); } .lp-siret-i.err { border-color:#dc2626; box-shadow:0 0 0 3px rgba(220,38,38,.12); } .lp-siret-btn { padding:9px 14px; font-family:inherit; font-size:.88rem; font-weight:600; white-space:nowrap; background:var(--ast-global-color-0,#006ae4); color:#fff; border:none; border-radius:var(--ast-border-radius,6px); cursor:pointer; transition:background .2s; } .lp-siret-btn:hover { background:var(--ast-global-color-1,#0051c0); } .lp-siret-btn:disabled { opacity:.6; cursor:not-allowed; } .lp-siret-fb { font-size:.75rem; font-weight:500; min-height:16px; } .lp-siret-fb.ok { color:#16a34a; } .lp-siret-fb.err { color:#dc2626; } .lp-siret-fb.loading { color:var(--ast-global-color-3,#888); } /* Bouton login */ .lp-login-btn { padding:9px 16px; font-family:inherit; font-size:.92rem; font-weight:600; color:var(--ast-global-color-0,#006ae4); border:1.5px solid var(--ast-global-color-0,#006ae4); border-radius:var(--ast-border-radius,6px); background:transparent; cursor:pointer; transition:background .2s,color .2s; } .lp-login-btn:hover { background:var(--ast-global-color-0,#006ae4); color:#fff; } /* Modal login */ .lp-modal-overlay { display:none; position:fixed; inset:0; background:rgba(0,0,0,.5); z-index:99999; align-items:center; justify-content:center; } .lp-modal-overlay.open { display:flex; } .lp-modal { background:#fff; border-radius:12px; padding:32px; max-width:440px; width:90%; position:relative; box-shadow:0 20px 60px rgba(0,0,0,.2); max-height:90vh; overflow-y:auto; } .lp-modal-close { position:absolute; top:12px; right:14px; background:none; border:none; font-size:1.4rem; cursor:pointer; color:var(--ast-global-color-3,#888); line-height:1; padding:4px; } .lp-modal-close:hover { color:#111; } .lp-modal-title { font-size:1.05rem; font-weight:700; margin-bottom:20px; color:var(--ast-global-color-2,#111); } /* Fix UAGB */ .wp-block-uagb-container::before,.wp-block-uagb-container::after, .wp-block-uagb-image::before,.wp-block-uagb-image::after { pointer-events:none !important; } /* ── Blocs service ── */ .latepoint-resources-items-w .resource-item { display:flex; flex-direction:column; gap:14px; padding:20px; border:1.5px solid var(--ast-border-color,#e5e7eb); border-radius:var(--ast-border-radius,8px); background:#fff; margin-bottom:12px; box-shadow:0 1px 4px rgba(0,0,0,.05); transition:box-shadow .2s; } .latepoint-resources-items-w .resource-item:hover { box-shadow:0 4px 16px rgba(0,0,0,.09); } .resource-item .ri-name h3 { margin:0; font-size:1.05rem; font-weight:700; color:var(--ast-global-color-2,#111); } .resource-item .ri-price { display:none; } .ri-price-tag { display:none; font-size:.85rem; font-weight:700; color:var(--ast-global-color-0,#006ae4); background:#eef4ff; border-radius:4px; padding:2px 8px; margin-top:2px; } .ri-price-tag.show { display:inline-block; } .resource-item .ri-description { font-size:.88rem; color:var(--ast-global-color-3,#666); } .ri-row { display:flex; align-items:flex-start; justify-content:space-between; flex-wrap:wrap; gap:16px; } .ri-left { display:flex; align-items:flex-start; gap:24px; flex-wrap:wrap; } /* Stepper */ .ri-att-w { display:flex; flex-direction:column; gap:6px; } .ri-att-lbl { font-size:.78rem; font-weight:600; text-transform:uppercase; letter-spacing:.05em; color:var(--ast-global-color-3,#666); } .ri-stepper { display:flex; align-items:center; border:1.5px solid var(--ast-border-color,#ddd); border-radius:6px; overflow:hidden; width:fit-content; } .ri-step-btn { width:34px; height:34px; background:#f5f5f5; border:none; font-size:1.1rem; font-weight:700; color:var(--ast-global-color-2,#333); cursor:pointer; display:flex; align-items:center; justify-content:center; transition:background .15s; line-height:1; } .ri-step-btn:hover { background:var(--ast-global-color-0,#006ae4); color:#fff; } .ri-step-btn:disabled { opacity:.35; cursor:not-allowed; } .ri-step-btn:disabled:hover { background:#f5f5f5; color:var(--ast-global-color-2,#333); } .ri-step-val { min-width:36px; text-align:center; font-size:.95rem; font-weight:700; padding:0 4px; background:#fff; color:var(--ast-global-color-2,#333); } .ri-att-bounds { font-size:.7rem; color:var(--ast-global-color-3,#999); } /* Agents */ .ri-agents-w { display:flex; flex-direction:column; gap:6px; } .ri-agents-lbl { font-size:.78rem; font-weight:600; text-transform:uppercase; letter-spacing:.05em; color:var(--ast-global-color-3,#666); } .ri-agents-list { display:flex; gap:12px; flex-wrap:wrap; } .ri-agent { display:flex; flex-direction:column; align-items:center; gap:6px; cursor:pointer; padding:8px; border-radius:10px; border:2px solid transparent; transition:border-color .15s,background .15s; min-width:80px; } .ri-agent:hover { border-color:var(--ast-global-color-0,#006ae4); background:#f0f6ff; } .ri-agent.selected { border-color:var(--ast-global-color-0,#006ae4); background:#e8f0fe; } .ri-agent-img { width:72px; height:72px; border-radius:50%; overflow:hidden; position:relative; flex-shrink:0; background:var(--ast-global-color-0,#006ae4); display:flex; align-items:center; justify-content:center; color:#fff; font-weight:700; font-size:1.1rem; } .ri-agent-img img { position:absolute; top:0; left:0; width:100%; height:100%; object-fit:cover; border-radius:50%; transition:opacity .25s; } .ri-agent-img .img-bio { opacity:1; z-index:1; } .ri-agent-img .img-avatar { opacity:0; z-index:2; } .ri-agent:hover .img-bio { opacity:0; } .ri-agent:hover .img-avatar { opacity:1; } .ri-agent-init { font-size:1.1rem; font-weight:700; color:#fff; } .ri-agent-name { font-size:.8rem; text-align:center; color:var(--ast-global-color-2,#333); font-weight:500; max-width:90px; line-height:1.3; word-break:break-word; } .n-full { display:block; } .n-pseudo { display:none; font-weight:700; color:var(--ast-global-color-0,#006ae4); } .ri-agent:hover .n-full { display:none; } .ri-agent:hover .n-pseudo { display:block; } /* Extras */ .ri-extras-w { display:flex; flex-direction:column; gap:6px; } .ri-extras-lbl { font-size:.78rem; font-weight:600; text-transform:uppercase; letter-spacing:.05em; color:var(--ast-global-color-3,#666); } .ri-extra-row { padding:3px 0; } .ri-extra-interactive { display:flex; align-items:center; gap:8px; cursor:pointer; font-size:.88rem; margin:0; } .ri-extra-interactive input[type="checkbox"] { width:16px; height:16px; cursor:pointer; accent-color:var(--ast-global-color-0,#006ae4); flex-shrink:0; } .ri-extra-ename { color:var(--ast-global-color-2,#333); } .ri-extra-price { color:var(--ast-global-color-0,#006ae4); font-weight:600; font-size:.82rem; } .ri-extra-name-only { font-size:.88rem; color:var(--ast-global-color-3,#777); } .ri-extra-name-only::before { content:"· "; color:var(--ast-global-color-3,#bbb); } .lp-hidden { display:none !important; } /* Bouton réserver */ .ri-buttons { margin-left:auto; align-self:flex-end; } .ri-buttons.locked { display:none !important; } .resource-item .ri-buttons .latepoint-book-button { display:inline-flex; align-items:center; gap:6px; padding:10px 22px; background:var(--ast-global-color-0,#006ae4); color:#fff !important; border-radius:var(--ast-border-radius,6px); font-weight:600; font-size:.92rem; text-decoration:none; border:none; cursor:pointer; transition:background .2s,transform .15s; white-space:nowrap; } .resource-item .ri-buttons .latepoint-book-button:hover:not([disabled]) { background:var(--ast-global-color-1,#0051c0); transform:translateY(-1px); } .resource-item .ri-buttons .latepoint-book-button[disabled], .resource-item .ri-buttons .latepoint-book-button.lp-btn-disabled { opacity:.5; cursor:not-allowed; transform:none; pointer-events:none; } /* Responsive */ @media(max-width:768px){ .lp-bar,.lp-access-row { flex-direction:column; align-items:flex-start; } .lp-access-or { padding-top:0; } .lp-sel-w,.lp-sel-w.wide,.lp-siret-i { min-width:100%; width:100%; } } @media(max-width:600px){ .ri-row { flex-direction:column; } .ri-buttons { margin-left:0; width:100%; align-self:auto; } .resource-item .ri-buttons .latepoint-book-button { width:100%; justify-content:center; } } .lp-visible { animation:lpFade .2s ease; } @keyframes lpFade { from{opacity:0;transform:translateY(4px)} to{opacity:1;transform:translateY(0)} } CSSBLOCK; wp_register_style( 'lp-ci', false ); wp_enqueue_style( 'lp-ci' ); wp_add_inline_style( 'lp-ci', $css ); // ── Données JS ──────────────────────────────────────────────────────── $j_G = wp_json_encode( array_values( $grouped ) ); $j_SL = wp_json_encode( $svc_loc ); $j_SVC = wp_json_encode( $services ); $j_ABS = wp_json_encode( $agents_by_svc ); $j_ALL = wp_json_encode( $all_agents ); $j_EXT = wp_json_encode( $extras_by_svc ); $j_IS_CUST = $is_cust ? 'true' : 'false'; $j_LOGGED = $logged_in ? 'true' : 'false'; $j_CUST_ID = wp_json_encode( $cust_id ); $j_SURL = wp_json_encode( $siret_url ); $j_SNONCE = wp_json_encode( $siret_nonce ); // ── JS ──────────────────────────────────────────────────────────────── $js = <<'; cat.locations.forEach(function(l) { html += ''; }); html += ''; }); return html; } // ── Accès ───────────────────────────────────────────────────────────── function refreshAccess() { canBook = IS_CUST || siretOk; $('.ri-price-tag').toggleClass('show', canBook); $('.ri-buttons').toggleClass('locked', !canBook); $('#lp-price-fg').toggle(canBook); $('.ri-extra-row').each(function() { $(this).find('.ri-extra-interactive').toggleClass('lp-hidden', !canBook); $(this).find('.ri-extra-name-only').toggleClass('lp-hidden', canBook); }); if (canBook) { $('#lp-notice').hide(); $('#lp-loc-wrap').slideDown(200); } updateBookButtons(); } function updateBookButtons() { if (!canBook) return; var ok = locId !== ''; $('.resource-item:not(.lp-hidden) .latepoint-book-button') .prop('disabled', !ok) .toggleClass('lp-btn-disabled', !ok); } // ── Recalcul prix total ─────────────────────────────────────────────── function recalcPrice(item) { if (!canBook) return; var sid = item.find('.latepoint-book-button').data('selected-service') + ''; var attendees = parseInt(item.find('.ri-step-val').text()) || 1; var total = (SVC[sid] || {}).price || 0; var extras = EXT[sid] || []; item.find('.ri-extra-cb:checked').each(function() { var eid = $(this).val(); var ext = null; for (var i = 0; i < extras.length; i++) { if (extras[i].id === eid) { ext = extras[i]; break; } } if (ext) total += ext.multiply ? ext.price * attendees : ext.price; }); item.find('.ri-price-tag').text('D\u00e8s ' + fmtPrice(total)); } // ── Barre de filtres (visible par tous) ─────────────────────────────── function buildFilterBar() { var bar = $('
'); var ao = ''; ALL.forEach(function(a) { ao += ''; }); bar.append( $('
') .append('Artiste') .append($('
') .append('')) ); var pg = $('
') .append('Trier par prix') .append($('
') .append('')); if (!canBook) pg.hide(); bar.append(pg); if (!IS_CUST) { bar.append(''); } return bar; } // ── Bloc accès ──────────────────────────────────────────────────────── function buildAccessBlock() { var block = $('
'); if (!IS_CUST) { block.hide(); block.append('
Renseignez votre SIRET professionnel ou connectez-vous pour acc\u00e9der aux tarifs et \u00e0 la r\u00e9servation.
'); var row = $('
'); row.append( $('
') .append('SIRET professionnel') .append($('
') .append('') .append('')) .append('
') ); row.append('
ou
'); row.append( $('
') .append('D\u00e9j\u00e0 client ?') .append('') ); block.append(row); } // Sélecteur lieu (toujours présent, visible après canBook=true) var locWrap = $('
'); if (!IS_CUST) locWrap.hide(); locWrap.append('
* S\u00e9lectionnez votre \u00e9tablissement pour activer la r\u00e9servation
'); locWrap.append( $('
') .append('Votre \u00e9tablissement *') .append($('
') .append('')) ); block.append(locWrap); return block; } // ── SIRET ───────────────────────────────────────────────────────────── function initSiret() { var input = $('#lp-siret'), btn = $('#lp-siret-btn'), fb = $('#lp-siret-fb'); if (!input.length) return; input.on('input', function() { var raw = $(this).val().replace(/\D/g, '').substring(0, 14), fmt = raw; if (raw.length > 9) fmt = raw.slice(0,3)+' '+raw.slice(3,6)+' '+raw.slice(6,9)+' '+raw.slice(9); else if (raw.length > 6) fmt = raw.slice(0,3)+' '+raw.slice(3,6)+' '+raw.slice(6); else if (raw.length > 3) fmt = raw.slice(0,3)+' '+raw.slice(3); $(this).val(fmt); if (siretOk) { siretOk = false; siretVal = ''; input.removeClass('ok err'); fb.text('').removeClass('ok err'); $('.latepoint-book-button').removeAttr('data-selected-custom-fields'); refreshAccess(); } }); function check() { var raw = input.val().replace(/\D/g, ''); if (raw.length !== 14) { fb.text('14 chiffres requis.').removeClass('ok loading').addClass('err'); input.removeClass('ok').addClass('err'); return; } btn.prop('disabled', true); fb.text('V\u00e9rification\u2026').removeClass('ok err').addClass('loading'); input.removeClass('ok err'); $.ajax({ url: SURL, method: 'POST', beforeSend: function(x) { x.setRequestHeader('X-WP-Nonce', SNONCE); }, contentType: 'application/json', data: JSON.stringify({siret: raw}), success: function(r) { btn.prop('disabled', false); if (r.success) { siretOk = true; siretVal = raw; input.addClass('ok').removeClass('err'); fb.text(r.message).removeClass('err loading').addClass('ok'); $('.latepoint-book-button').attr('data-selected-custom-fields', JSON.stringify({'cf_CNKHUXiS': raw})); } else { siretOk = false; siretVal = ''; input.addClass('err').removeClass('ok'); fb.text(r.message).removeClass('ok loading').addClass('err'); $('.latepoint-book-button').removeAttr('data-selected-custom-fields'); } refreshAccess(); }, error: function() { btn.prop('disabled', false); fb.text('Erreur r\u00e9seau.').removeClass('ok loading').addClass('err'); } }); } btn.on('click', check); input.on('keydown', function(e) { if (e.key === 'Enter') check(); }); } // ── Modal login ─────────────────────────────────────────────────────── function buildLoginModal() { if ($('#lp-modal-overlay').length) return; var overlay = $('
'); var modal = $('
'); var close = $(''); var existing = $('.latepoint-form').first(); var content = existing.length ? existing.clone(true, true) : $('

Connectez-vous \u00e0 votre espace client.

Mon espace
'); modal.append(close).append('
Connexion \u00e0 votre compte
').append(content); overlay.append(modal); $('body').append(overlay); close.on('click', function() { overlay.removeClass('open'); }); overlay.on('click', function(e) { if ($(e.target).is(overlay)) overlay.removeClass('open'); }); } // ── Filtrage ────────────────────────────────────────────────────────── function applyFilters() { var container = $('.latepoint-resources-items-w').first(); container.find('.resource-item').each(function() { var item = $(this), btn = item.find('.latepoint-book-button'); var sid = btn.data('selected-service') + ''; var show = true; if (locId) { var m = (SL[sid] || []).indexOf(locId) !== -1; if (!m) show = false; if (m) btn.attr('data-selected-location', locId); else btn.removeAttr('data-selected-location'); } else { btn.removeAttr('data-selected-location'); } if (show && agentId) { var found = false; var ag = ABS[sid] || []; for (var i = 0; i < ag.length; i++) { if (ag[i].id === agentId) { found = true; break; } } if (!found) show = false; } item.toggleClass('lp-hidden', !show).toggleClass('lp-visible', show); }); if (agentId) { container.find('.resource-item:not(.lp-hidden)').each(function() { var item = $(this); var card = item.find('.ri-agent[data-id="' + agentId + '"]'); if (card.length) { item.find('.ri-agent').removeClass('selected'); card.addClass('selected'); item.find('.latepoint-book-button').attr('data-selected-agent', agentId); } }); } if (priceSort && canBook) { var items = container.find('.resource-item:not(.lp-hidden)').toArray(); items.sort(function(a, b) { var sa = $(a).find('.latepoint-book-button').data('selected-service') + ''; var sb = $(b).find('.latepoint-book-button').data('selected-service') + ''; var pa = (SVC[sa] || {}).price || 0, pb = (SVC[sb] || {}).price || 0; return priceSort === 'asc' ? pa - pb : pb - pa; }); items.forEach(function(el) { container.append(el); }); } updateBookButtons(); } // ── Init ────────────────────────────────────────────────────────────── function initFilters() { if ($('.lp-bar').length) return; var block = $('.latepoint-resources-items-w').first(); if (!block.length) return; var bar = buildFilterBar(); var abl = buildAccessBlock(); block.before(abl); abl.before(bar); $('#lp-agent').on('change', function() { agentId = $(this).val(); applyFilters(); }); $('#lp-price').on('change', function() { priceSort = $(this).val(); applyFilters(); }); $(document).on('click', '#lp-vp-btn', function() { $(this).fadeOut(200, function() { $(this).remove(); }); $('#lp-access-block').slideDown(300); initSiret(); }); $(document).on('click', '#lp-login-btn', function(e) { e.preventDefault(); $('#lp-modal-overlay').addClass('open'); }); $(document).on('change', '#lp-loc', function() { locId = $(this).val(); if (locId) $('#lp-loc-notice').hide(); applyFilters(); }); buildLoginModal(); } // ── Carte agent ─────────────────────────────────────────────────────── function agentCard(a, first) { var imgs = ''; if (a.bio) imgs += '' + a.name + ''; if (a.avatar) imgs += '' + a.name + ''; if (!imgs) imgs = '' + a.init + ''; return '
' + '
' + imgs + '
' + '
' + a.name + '' + (a.display || a.name) + '
' + '
'; } // ── Amélioration des blocs service ──────────────────────────────────── function enhanceItems() { $('.latepoint-resources-items-w .resource-item').each(function() { var item = $(this); if (item.data('done')) return; item.data('done', true); var btn = item.find('.latepoint-book-button'); var sid = btn.data('selected-service') + ''; var ag = ABS[sid] || []; var cap = SVC[sid] || {min: 1, max: 99, price: 0}; var ext = EXT[sid] || []; var val = midpoint(cap.min, cap.max); // Prix tag if (cap.price > 0) { var pt = $('D\u00e8s ' + fmtPrice(cap.price) + ''); if (canBook) pt.addClass('show'); item.find('.ri-name').after(pt); } // Stepper var minus = $(''); var plus = $(''); var count = $('' + val + ''); if (val <= cap.min) minus.prop('disabled', true); if (val >= cap.max) plus.prop('disabled', true); var att = $('
') .append('
Participants
') .append($('
').append(minus).append(count).append(plus)) .append('
min ' + cap.min + ' \u2014 max ' + cap.max + '
'); // Agents var agw = null; if (ag.length) { var cards = ag.map(function(a, i) { return agentCard(a, i === 0); }).join(''); agw = $('
') .append('
' + (ag.length > 1 ? 'Intervenants' : 'Intervenant') + '
') .append('
' + cards + '
'); } // Extras var extw = null; if (ext.length) { extw = $('
').append('
Extras possibles
'); ext.forEach(function(e) { var priceStr = canBook ? ' +' + fmtPrice(e.price) + (e.multiply ? '/pers.' : '') + '' : ''; var interactive = $(''); var readonly = $('' + e.name + ''); extw.append($('
').append(interactive).append(readonly)); }); } // Assemblage var left = $('
').append(att); if (agw) left.append(agw); if (extw) left.append(extw); var bw = item.find('.ri-buttons').detach(); if (!canBook) bw.addClass('locked'); if (canBook && !locId) bw.find('.latepoint-book-button').prop('disabled', true).addClass('lp-btn-disabled'); item.append($('
').append(left).append(bw)); // Attributs LatePoint btn.attr('data-hide-side-panel', 'yes'); btn.attr('data-selected-total-attendees', val); if (ag.length) btn.attr('data-selected-agent', ag[0].id); if (LOGGED && CUST_ID) btn.attr('data-selected-customer', CUST_ID); if (locId) btn.attr('data-selected-location', locId); // Stepper events item.on('click', '.ri-step-btn', function() { var cur = parseInt(count.text()) || cap.min; var isP = $(this).hasClass('ri-plus'); if (isP && cur < cap.max) { cur++; minus.prop('disabled', false); if (cur >= cap.max) plus.prop('disabled', true); } if (!isP && cur > cap.min) { cur--; plus.prop('disabled', false); if (cur <= cap.min) minus.prop('disabled', true); } count.text(cur); btn.attr('data-selected-total-attendees', cur); recalcPrice(item); }); // Extra events item.on('change', '.ri-extra-cb', function() { var eid = $(this).val(); if (!selectedExtras[sid]) selectedExtras[sid] = []; if ($(this).prop('checked')) { if (selectedExtras[sid].indexOf(eid) === -1) selectedExtras[sid].push(eid); } else { selectedExtras[sid] = selectedExtras[sid].filter(function(x) { return x !== eid; }); } recalcPrice(item); }); // Agent events item.on('click', '.ri-agent', function() { item.find('.ri-agent').removeClass('selected'); $(this).addClass('selected'); btn.attr('data-selected-agent', $(this).data('id')); }); }); } // ── MutationObserver popup ──────────────────────────────────────────── $(document).on('mousedown', '.latepoint-book-button', function() { $('.latepoint-book-button').removeAttr('data-lp-active'); $(this).attr('data-lp-active', 'yes'); activeBtn = $(this); }); new MutationObserver(function(muts) { muts.forEach(function(m) { m.addedNodes.forEach(function(n) { if (!n.querySelector) return; var popup = $(n).hasClass('os-booking-w') ? $(n) : $(n).find('.os-booking-w'); if (!popup.length || !activeBtn) return; var att = parseInt(activeBtn.attr('data-selected-total-attendees') || 1); var sid = activeBtn.data('selected-service') + ''; // Attendees setTimeout(function() { var sels = [ 'input[name="booking[total_attendees]"]', 'input[name="total_attendees"]', '.os-total-attendees-selector input', '.os-stepper[data-param="total_attendees"] .os-stepper-value', '[data-param-name="total_attendees"] input' ]; sels.forEach(function(s) { var f = popup.find(s); if (f.length) f.val(att).trigger('change').trigger('input'); }); }, 300); // Extras var extWrapper = popup.find('.latepoint-service-extras-for-booking-wrapper')[0]; if (extWrapper && selectedExtras[sid] && selectedExtras[sid].length) { new MutationObserver(function(_, obs) { selectedExtras[sid].forEach(function(eid) { popup.find('input[type="checkbox"][value="' + eid + '"]').prop('checked', true).trigger('change'); }); obs.disconnect(); }).observe(extWrapper, {childList: true, subtree: true}); } }); }); }).observe(document.body, {childList: true, subtree: true}); // ── Démarrage ───────────────────────────────────────────────────────── $(window).on('load', function() { initFilters(); enhanceItems(); refreshAccess(); var t = document.querySelector('.entry-content, main, #primary'); if (t) new MutationObserver(function() { initFilters(); enhanceItems(); }).observe(t, {childList: true, subtree: true}); }); })(jQuery); JSBLOCK; wp_add_inline_script( 'jquery', $js ); } add_action( 'wp_enqueue_scripts', 'latepoint_custom_enhancements' );